import { JSX } from 'react';
import { RenderElementProps, RenderLeafProps } from 'slate-react';
import { Plugin } from '@/plugins/types';
import { NodeEntry, Range } from 'slate';
import { KEY_EVENT } from '@/plugins/config';

export const renderElement = (props: RenderElementProps, plugins: Plugin[]): JSX.Element => {
  const context = {
    children: props.children,
    props,
    classList: [],
  };

  for (const plugin of plugins) {
    if (plugin.match && plugin.match(props) && plugin.render) {
      context.children = plugin.render(context);
    }
  }

  return (
    <div {...props.attributes} className={context.classList.join(' ')}>
      {context.children}
    </div>
  );
};
export const renderLeaf = (props: RenderLeafProps, plugins: Plugin[]): JSX.Element => {
  const context = {
    children: props.children,
    props,
    classList: [],
    style: {},
  };

  for (const plugin of plugins) {
    if (plugin.matchLeaf && plugin.matchLeaf(props) && plugin.renderLeaf) {
      context.children = plugin.renderLeaf(context);
    }
  }

  return (
    <span {...props.attributes} style={context.style} className={context.classList.join(' ')}>
      {context.children}
    </span>
  );
};

export const onKeyDown = (event: KeyboardEvent, plugins: Plugin[]): void => {
  for (const plugin of plugins) {
    const text = plugin.onKeyDown && plugin.onKeyDown(event);
    if (text === KEY_EVENT.Stop) break;
  }
};

export const decorate = (entry: NodeEntry, plugins: Plugin[]): Range[] => {
  const range: Range[] = [];
  for (const plugin of plugins) {
    let result: Range[] = [];
    if (plugin.decorate && (result = plugin.decorate(entry))) {
      range.push(...result);
    }
  }
  return range;
};
